{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Matrix Multiplication\n",
    "\n",
    "## Dense matrix multiplication"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[0 4]\n"
     ]
    }
   ],
   "source": [
    "import numpy as np\n",
    "\n",
    "# message passing (MP)\n",
    "x = np.array([2, 0])\n",
    "A = np.array([[0, 2], [2, 0]])\n",
    "\n",
    "y = x @ A\n",
    "\n",
    "print(y)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[[0.  0.5]\n",
      "  [0.5 0. ]]\n",
      "\n",
      " [[0.  0. ]\n",
      "  [0.  0. ]]\n",
      "\n",
      " [[0.  0. ]\n",
      "  [0.  0. ]]]\n",
      "[[0.  0.5]\n",
      " [0.5 0. ]]\n"
     ]
    }
   ],
   "source": [
    "# predicate activation\n",
    "p = np.array([[[0.5, 0, 1]]])\n",
    "A = np.array([[[0, 1], [1, 0]], [[0, 0], [1, 0]], [[0, 0], [0, 0]]])\n",
    "\n",
    "_A = p.T*A\n",
    "print(_A)\n",
    "\n",
    "_A = _A.sum(0)\n",
    "print(_A)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[0.  1.9]\n",
      " [0.9 0. ]]\n",
      "[0.09 1.71]\n"
     ]
    }
   ],
   "source": [
    "# predicate activation + MP\n",
    "x = np.array([0.9, 0.1])\n",
    "p = np.array([[[0.9, 0, 1]]])\n",
    "A = np.array([[[0, 1], [1, 0]], [[0, 0], [1, 0]], [[0, 1], [0, 0]]])\n",
    "\n",
    "_A = (p.T*A).sum(0)\n",
    "print(_A)\n",
    "y = x @ _A\n",
    "print(y)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[0.45 0.  ]\n",
      " [0.   1.52]]\n",
      "[[0.5 0. ]\n",
      " [0.  0. ]]\n",
      "[[0.95 0.  ]\n",
      " [0.   1.52]\n",
      " [0.45 1.52]\n",
      " [0.5  0.  ]]\n",
      "[1.9  3.04]\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "array([3, 2])"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# score aggregation E1 E2 P1 P2\n",
    "\n",
    "n_entities = 2\n",
    "n_predicates = 3\n",
    "\n",
    "A = np.array([[[0, 1], [1, 0]], [[0, 0], [1, 0]], [[0, 1], [0, 0]]])\n",
    "x = np.array([[0, 0.5], [0.8, 0]])\n",
    "\n",
    "p1 = np.array([[[0.9, 0, 1]]])\n",
    "p2 = np.array([[[0, 1, 0]]])\n",
    "\n",
    "ps = [p1, p2]\n",
    "\n",
    "ye = np.zeros((x.shape[0], n_entities))\n",
    "yp = np.zeros((len(ps), n_entities))\n",
    "for i, p in enumerate(ps):\n",
    "    _A = (p.T*A).sum(0)\n",
    "    _y = x @ _A\n",
    "    yp[i] = _y.sum(0)\n",
    "    ye += _y\n",
    "    print(_y)\n",
    "\n",
    "y = np.vstack([ye,yp])\n",
    "print(y)\n",
    "print(y.sum(0))\n",
    "\n",
    "# activations across components\n",
    "threshold = 0\n",
    "a = np.where(y>threshold)[1]\n",
    "np.bincount(a)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Sparse matrix multiplication"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "ename": "NameError",
     "evalue": "name 'np' is not defined",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mNameError\u001b[0m                                 Traceback (most recent call last)",
      "\u001b[0;32m<ipython-input-2-b41002ec8556>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[1;32m      2\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m      3\u001b[0m \u001b[0;31m# message passing (MP)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 4\u001b[0;31m \u001b[0mx\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0msp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcsr_matrix\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mnp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0marray\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m2\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m0\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m      5\u001b[0m \u001b[0mA\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0msp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcsr_matrix\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mnp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0marray\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m2\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0;36m2\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m0\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m      6\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;31mNameError\u001b[0m: name 'np' is not defined"
     ]
    }
   ],
   "source": [
    "import scipy.sparse as sp\n",
    "\n",
    "# message passing (MP)\n",
    "x = sp.csr_matrix(np.array([2, 0]))\n",
    "A = sp.csr_matrix(np.array([[0, 2], [2, 0]]))\n",
    "\n",
    "y = x @ A\n",
    "\n",
    "print(y)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[<2x2 sparse matrix of type '<class 'numpy.float64'>'\n",
      "\twith 2 stored elements in Compressed Sparse Row format>\n",
      " <2x2 sparse matrix of type '<class 'numpy.float64'>'\n",
      "\twith 1 stored elements in Compressed Sparse Row format>\n",
      " <2x2 sparse matrix of type '<class 'numpy.float64'>'\n",
      "\twith 0 stored elements in Compressed Sparse Row format>]\n",
      "  (0, 1)\t0.5\n",
      "  (1, 0)\t0.5\n"
     ]
    }
   ],
   "source": [
    "# predicate activation\n",
    "p = np.array([0.5, 0, 1])\n",
    "A = [[[0, 1], [1, 0]], [[0, 0], [1, 0]], [[0, 0], [0, 0]]]\n",
    "A = [sp.csr_matrix(a) for a in A]\n",
    "# print(A)\n",
    "\n",
    "_A = p*A\n",
    "print(_A)\n",
    "\n",
    "_A = sum(_A)\n",
    "print(_A)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "  (0, 1)\t1.9\n",
      "  (1, 0)\t0.9\n",
      "  (0, 0)\t0.09000000000000001\n",
      "  (0, 1)\t1.71\n"
     ]
    }
   ],
   "source": [
    "# predicate activation + MP\n",
    "x = sp.csr_matrix(np.array([0.9, 0.1]))\n",
    "p = np.array([0.9, 0, 1])\n",
    "A = [[[0, 1], [1, 0]], [[0, 0], [1, 0]], [[0, 1], [0, 0]]]\n",
    "A = [sp.csr_matrix(a) for a in A]\n",
    "\n",
    "_A = sum(p*A)\n",
    "print(_A)\n",
    "\n",
    "y = x @ _A\n",
    "print(y)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "  (0, 0)\t0.95\n",
      "  (0, 1)\t1.71\n",
      "  (1, 0)\t0.19\n",
      "  (1, 1)\t1.52\n",
      "  (2, 0)\t0.54\n",
      "  (2, 1)\t3.23\n",
      "  (3, 0)\t0.6\n",
      "  (3, 1)\t0.0\n",
      "[0.35294118 1.        ]\n",
      "  (0, 0)\t1.0\n",
      "  (0, 1)\t1.0\n",
      "  (1, 0)\t1.0\n",
      "  (1, 1)\t1.0\n",
      "  (2, 0)\t1.0\n",
      "  (2, 1)\t1.0\n",
      "  (3, 0)\t1.0\n",
      "[4. 3.]\n",
      "[4.35294118 4.        ]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/home/zola/anaconda3/envs/tf36/lib/python3.6/site-packages/scipy/sparse/compressed.py:746: SparseEfficiencyWarning: Changing the sparsity structure of a csr_matrix is expensive. lil_matrix is more efficient.\n",
      "  SparseEfficiencyWarning)\n"
     ]
    }
   ],
   "source": [
    "# score aggregation E1 E2 P1 P2\n",
    "from sklearn.preprocessing import normalize, binarize\n",
    "\n",
    "threshold = 0\n",
    "n_entities = 2\n",
    "\n",
    "A = [[[0, 1], [1, 0]], [[0, 0], [1, 0]], [[0, 1], [0, 0]]]\n",
    "A = [sp.csr_matrix(a) for a in A]\n",
    "x = sp.csr_matrix(np.array([[0.9, 0.5], [0.8, 0.1]]))\n",
    "\n",
    "p1 = np.array([0.9, 0, 1])\n",
    "p2 = np.array([0, 1, 0])\n",
    "\n",
    "ps = [p1, p2]\n",
    "\n",
    "ye = sp.csr_matrix((x.shape[0], n_entities))\n",
    "yp = sp.csr_matrix((len(ps), n_entities))\n",
    "for i, p in enumerate(ps):\n",
    "    _A = sum(p*A)\n",
    "    _y = x @ _A\n",
    "    yp[i] = _y.sum(0)\n",
    "    ye += _y\n",
    "\n",
    "y = sp.vstack([ye,yp])\n",
    "print(y)\n",
    "sum_a = sum(y)\n",
    "sum_a_norm = normalize(sum_a, norm='max', axis=1).toarray()[0]\n",
    "print(sum_a_norm)\n",
    "\n",
    "# activations across components\n",
    "y_counts = binarize(y, threshold=0.0)\n",
    "print(w_normalized)\n",
    "count_a = sum(y_counts).toarray()[0]\n",
    "print(count_a)\n",
    "\n",
    "scores = sum_a_norm + count_a\n",
    "print(scores)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "tf36",
   "language": "python",
   "name": "tf36"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.7"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
